home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
176_01
/
xllist.c
< prev
next >
Wrap
Text File
|
1985-12-19
|
19KB
|
838 lines
/* xllist - xlisp built-in list functions */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
#ifdef MEGAMAX
overlay "overflow"
#endif
/* external variables */
extern NODE ***xlstack;
extern NODE *s_unbound;
extern NODE *true;
/* external routines */
extern int eq(),eql(),equal();
/* forward declarations */
FORWARD NODE *cxr();
FORWARD NODE *nth(),*assoc();
FORWARD NODE *subst(),*sublis(),*map();
FORWARD NODE *cequal();
/* cxr functions */
NODE *xcar(args) NODE *args; { return (cxr(args,"a")); }
NODE *xcdr(args) NODE *args; { return (cxr(args,"d")); }
/* cxxr functions */
NODE *xcaar(args) NODE *args; { return (cxr(args,"aa")); }
NODE *xcadr(args) NODE *args; { return (cxr(args,"da")); }
NODE *xcdar(args) NODE *args; { return (cxr(args,"ad")); }
NODE *xcddr(args) NODE *args; { return (cxr(args,"dd")); }
/* cxxxr functions */
NODE *xcaaar(args) NODE *args; { return (cxr(args,"aaa")); }
NODE *xcaadr(args) NODE *args; { return (cxr(args,"daa")); }
NODE *xcadar(args) NODE *args; { return (cxr(args,"ada")); }
NODE *xcaddr(args) NODE *args; { return (cxr(args,"dda")); }
NODE *xcdaar(args) NODE *args; { return (cxr(args,"aad")); }
NODE *xcdadr(args) NODE *args; { return (cxr(args,"dad")); }
NODE *xcddar(args) NODE *args; { return (cxr(args,"add")); }
NODE *xcdddr(args) NODE *args; { return (cxr(args,"ddd")); }
/* cxxxxr functions */
NODE *xcaaaar(args) NODE *args; { return (cxr(args,"aaaa")); }
NODE *xcaaadr(args) NODE *args; { return (cxr(args,"daaa")); }
NODE *xcaadar(args) NODE *args; { return (cxr(args,"adaa")); }
NODE *xcaaddr(args) NODE *args; { return (cxr(args,"ddaa")); }
NODE *xcadaar(args) NODE *args; { return (cxr(args,"aada")); }
NODE *xcadadr(args) NODE *args; { return (cxr(args,"dada")); }
NODE *xcaddar(args) NODE *args; { return (cxr(args,"adda")); }
NODE *xcadddr(args) NODE *args; { return (cxr(args,"ddda")); }
NODE *xcdaaar(args) NODE *args; { return (cxr(args,"aaad")); }
NODE *xcdaadr(args) NODE *args; { return (cxr(args,"daad")); }
NODE *xcdadar(args) NODE *args; { return (cxr(args,"adad")); }
NODE *xcdaddr(args) NODE *args; { return (cxr(args,"ddad")); }
NODE *xcddaar(args) NODE *args; { return (cxr(args,"aadd")); }
NODE *xcddadr(args) NODE *args; { return (cxr(args,"dadd")); }
NODE *xcdddar(args) NODE *args; { return (cxr(args,"addd")); }
NODE *xcddddr(args) NODE *args; { return (cxr(args,"dddd")); }
/* cxr - common car/cdr routine */
LOCAL NODE *cxr(args,adstr)
NODE *args; char *adstr;
{
NODE *list;
/* get the list */
list = xlmatch(LIST,&args);
xllastarg(args);
/* perform the car/cdr operations */
while (*adstr && consp(list))
list = (*adstr++ == 'a' ? car(list) : cdr(list));
/* make sure the operation succeeded */
if (*adstr && list)
xlfail("bad argument");
/* return the result */
return (list);
}
/* xcons - construct a new list cell */
NODE *xcons(args)
NODE *args;
{
NODE *arg1,*arg2;
/* get the two arguments */
arg1 = xlarg(&args);
arg2 = xlarg(&args);
xllastarg(args);
/* construct a new list element */
return (cons(arg1,arg2));
}
/* xlist - built a list of the arguments */
NODE *xlist(args)
NODE *args;
{
NODE ***oldstk,*arg,*list,*val,*last,*lptr;
/* create a new stack frame */
oldstk = xlsave(&arg,&list,&val,NULL);
/* initialize */
arg = args;
/* evaluate and append each argument */
for (last = NIL; arg; last = lptr) {
/* evaluate the next argument */
val = xlarg(&arg);
/* append this argument to the end of the list */
lptr = consa(val);
if (last == NIL)
list = lptr;
else
rplacd(last,lptr);
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the list */
return (list);
}
/* xappend - built-in function append */
NODE *xappend(args)
NODE *args;
{
NODE ***oldstk,*arg,*list,*last,*val,*lptr;
/* create a new stack frame */
oldstk = xlsave(&arg,&list,&last,&val,NULL);
/* initialize */
arg = args;
/* evaluate and append each argument */
while (arg) {
/* evaluate the next argument */
list = xlmatch(LIST,&arg);
/* append each element of this list to the result list */
while (consp(list)) {
/* append this element */
lptr = consa(car(list));
if (last == NIL)
val = lptr;
else
rplacd(last,lptr);
/* save the new last element */
last = lptr;
/* move to the next element */
list = cdr(list);
}
}
/* restore previous stack frame */
xlstack = oldstk;
/* return the list */
return (val);
}
/* xreverse - built-in function reverse */
NODE *xreverse(args)
NODE *args;
{
NODE ***oldstk,*list,*val;
/* create a new stack frame */
oldstk = xlsave(&list,&val,NULL);
/* get the list to reverse */
list = xlmatch(LIST,&args);
xllastarg(args);
/* append each element of this list to the result list */
while (consp(list)) {
/* append this element */
val = cons(car(list),val);
/* move to the next element */
list = cdr(list);
}
/* restore previous stack frame */
xlstack = oldstk;
/* return the list */
return (val);
}
/* xlast - return the last cons of a list */
NODE *xlast(args)
NODE *args;
{
NODE *list;
/* get the list */
list = xlmatch(LIST,&args);
xllastarg(args);
/* find the last cons */
while (consp(list) && cdr(list))
list = cdr(list);
/* return the last element */
return (list);
}
/* xmember - built-in function 'member' */
NODE *xmember(args)
NODE *args;
{
NODE ***oldstk,*x,*list,*fcn,*val;
int tresult;
/* create a new stack frame */
oldstk = xlsave(&x,&list,&fcn,NULL);
/* get the expression to look for and the list */
x = xlarg(&args);
list = xlmatch(LIST,&args);
xltest(&fcn,&tresult,&args);
xllastarg(args);
/* look for the expression */
for (val = NIL; consp(list); list = cdr(list))
if (dotest(x,car(list),fcn) == tresult) {
val = list;
break;
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* xassoc - built-in function 'assoc' */
NODE *xassoc(args)
NODE *args;
{
NODE ***oldstk,*x,*alist,*fcn,*pair,*val;
int tresult;
/* create a new stack frame */
oldstk = xlsave(&x,&alist,&fcn,NULL);
/* get the expression to look for and the association list */
x = xlarg(&args);
alist = xlmatch(LIST,&args);
xltest(&fcn,&tresult,&args);
xllastarg(args);
/* look for the expression */
for (val = NIL; consp(alist); alist = cdr(alist))
if ((pair = car(alist)) && consp(pair))
if (dotest(x,car(pair),fcn) == tresult) {
val = pair;
break;
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* xsubst - substitute one expression for another */
NODE *xsubst(args)
NODE *args;
{
NODE ***oldstk,*to,*from,*expr,*fcn,*val;
int tresult;
/* create a new stack frame */
oldstk = xlsave(&to,&from,&expr,&fcn,NULL);
/* get the to value, the from value and the expression */
to = xlarg(&args);
from = xlarg(&args);
expr = xlarg(&args);
xltest(&fcn,&tresult,&args);
xllastarg(args);
/* do the substitution */
val = subst(to,from,expr,fcn,tresult);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* subst - substitute one expression for another */
LOCAL NODE *subst(to,from,expr,fcn,tresult)
NODE *to,*from,*expr,*fcn; int tresult;
{
NODE ***oldstk,*carval,*cdrval,*val;
if (dotest(expr,from,fcn) == tresult)
val = to;
else if (consp(expr)) {
oldstk = xlsave(&carval,&cdrval,NULL);
carval = subst(to,from,c